package Initialization_Sequence;/*
 *
 * @author 陈粒
 * @version 创建时间：2021/7/9 9:41
 */

import org.junit.Test;

/**
 * java中父类和子类初始化顺序:
 * 顺序:
 * 1. 父类中静态成员变量和静态代码块
 *
 * 2. 子类中静态成员变量和静态代码块
 *
 * 3. 父类中普通成员变量和代码块，父类的构造函数
 *
 * 4. 子类中普通成员变量和代码块，子类的构造函数
 * 注意：其中“和”字两端的按照代码先后顺序执行。
 * 结论:执行顺序:静态代码块 --> 构造代码块 --> 构造方法 --> 局部代码块
 */

public class Initialization_Sequence {//测试类

    public static void main(String[] args) {

        new Son();
    }
}

class Father {//父类

    public String fStr1 = "father1";
    protected String fStr2 = "father2";
    private String fStr3 = "father3";
    Teacher t1=new Teacher("用来初始化父类Father引用变量t1");

    static {

        System.out.println("父类静态代码块");
    }

    public Father() {
        System.out.println("父类构造函数");
    }
    {
        System.out.println("父类构造代码块");
    }
}
class Teacher{
    public Teacher(String s) {
        System.out.println("Teacher含参构造函数 "+s);
    }
    {
        System.out.println("Teacher构造代码块");
    }
    static{
        System.out.println("Teacher静态代码块");
    }

}
class Son extends Father {//子类
    public String SStr1 = "Son1";
    protected String SStr2 = "Son2";
    private String SStr3 = "Son3";
    Teacher t2=new Teacher("用来初始化子类Son引用变量t2");

    {
        System.out.println("子类构造代码块");
    }

    static {
        System.out.println("子类静态代码块");
    }

    public Son() {
        //super();
            System.out.println("子类构造函数");
    }

/**
 *总结：
 * 1，在类加载的时候执行父类的static代码块，并且只执行一次（因为类只加载一次）；
 *
 * 2，执行子类的static代码块，并且只执行一次（因为类只加载一次）；
 *
 * 3，执行父类的类成员初始化，并且是从上往下按出现顺序执行（在debug时可以看出）。
 *
 * 4，执行父类的构造函数；
 *
 * 5，执行子类的类成员初始化，并且是从上往下按出现顺序执行。
 *
 * 6，执行子类的构造函数。
 */
}
